package com.yanqu.road.server.gameplayer.module.manor;

import com.yanqu.road.entity.config.manor.ManorTechnologyConfig;
import com.yanqu.road.entity.config.skill.SkillInfo;
import com.yanqu.road.entity.config.skill.SkillUpgradeInfo;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.enums.eLogMoneyType;
import com.yanqu.road.entity.enums.ePlayerAttrType;
import com.yanqu.road.entity.enums.eSkillType;
import com.yanqu.road.entity.log.LogManorTechnologySkillLvUp;
import com.yanqu.road.entity.manor.ManorTechnologyData;
import com.yanqu.road.entity.player.UserBeauty;
import com.yanqu.road.entity.task.args.ManorRechargeArgs;
import com.yanqu.road.logic.bussiness.player.UserManorBusiness;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.pb.manor.ManorProto;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.patrons.PatronsModule;
import com.yanqu.road.server.gameplayer.module.player.AttributeModule;
import com.yanqu.road.server.gameplayer.module.player.BeautyModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.gameplayer.module.player.EarnSpeedModule;
import com.yanqu.road.server.gameplayer.module.skin.SkinModule;
import com.yanqu.road.server.manger.config.SkillMgr;
import com.yanqu.road.server.manger.log.LogMgr;
import com.yanqu.road.server.manger.manor.ManorMgr;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;

import java.math.BigInteger;
import java.util.*;

/**
 * @author ：zfr
 * @date ：2021/5/10 18:59
 */
public class ManorTechnologyModel {
    private Map<Integer, ManorTechnologyData> technologyDataMap;
    private GamePlayer player;

    public ManorTechnologyModel(Map<Integer, ManorTechnologyData> technologyDataMap, GamePlayer player) {
        this.technologyDataMap = technologyDataMap;
        this.player = player;
    }

    public Map<Integer, ManorTechnologyData> getTechnologyDataMap() {
        return technologyDataMap;
    }

    public int unLock(int id, int skillPos) {
        ManorTechnologyConfig manorTechnologyConfig = ManorMgr.getManorTechnologyConfigMap().get(id);
        if (manorTechnologyConfig == null) {
            return GameErrorCode.E_MANOR_CONFIG_NO_FOUND;
        }
        if (player.getUserInfo().getTitleId() < manorTechnologyConfig.getUnlock()) {
            return GameErrorCode.E_MANOR_TITLE_ID_LIMIT;
        }
        if (getSkillMaxLevel(id, skillPos) <= 0) {
            return GameErrorCode.E_MANOR_UNLOCK_LIMIT;
        }
        if (technologyDataMap.get(id) != null && technologyDataMap.get(id).getSkillLvList().size() > skillPos && technologyDataMap.get(id).getSkillLvList().get(skillPos) > 0) {
            return GameErrorCode.E_MANOR_OBJ_IS_UNLOCK;
        }
        if (new BigInteger(manorTechnologyConfig.getUnlockCost().get(skillPos)).compareTo(BigInteger.ZERO) > 0) {
            if (!player.getModule(CurrencyModule.class).removeCurrency(new Property(manorTechnologyConfig.getUpgradeItem(), new BigInteger(manorTechnologyConfig.getUnlockCost().get(skillPos))), eLogMoneyType.Manor, eLogMoneyType.ManorUnLockTechnologyCost)) {
                return GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
            }
        }
        ManorTechnologyData technologyData = technologyDataMap.get(id);
        if (technologyData == null) {
            technologyData = new ManorTechnologyData();
            technologyData.setUserId(player.getUserId());
            technologyData.setId(manorTechnologyConfig.getId());
            technologyData.setInsertOption();
            technologyDataMap.put(id, technologyData);
        }
        technologyData.unlockSkill(skillPos);
        player.getModule(ManorModule.class).addProsperousValue(ManorMgr.getTechnologySkillLvUpProsperousAdd().get(skillPos), "科技解锁");
        player.getModule(ManorModule.class).syncManorData();
        notifyAdd(id, skillPos);
        LogMgr.addLogManorTechnologySkillLvUp(new LogManorTechnologySkillLvUp(player.getUserId(), id, skillPos, 0, 1, 1,
                manorTechnologyConfig.getUpgradeItem() + "=" + manorTechnologyConfig.getUnlockCost().get(skillPos), new Date()));
        return 0;
    }

    public void technologyLevelUp(int id, int skillPos, int lvCount, ManorProto.ManorTechnologyLevelUpRespMsg.Builder respMsg) {
        ManorTechnologyData technologyData = technologyDataMap.get(id);
        if (technologyData == null) {
            respMsg.setRet(GameErrorCode.E_MANOR_OBJ_IS_LOCK);
            return;
        }
        ManorTechnologyConfig manorTechnologyConfig = ManorMgr.getManorTechnologyConfigMap().get(id);
        if (manorTechnologyConfig == null) {
            respMsg.setRet(GameErrorCode.E_MANOR_CONFIG_NO_FOUND);
            return;
        }
        SkillInfo skillInfo = SkillMgr.getSkillInfo(manorTechnologyConfig.getVolumesIdList().get(skillPos));
        if (skillInfo == null) {
            respMsg.setRet(GameErrorCode.E_MANOR_SKILL_INFO_NO_FOUND);
            return;
        }
        if (lvCount > 1 && player.getModule(ManorModule.class).getUserManorData().getProsperousValue() < GameConfig.MANOR_TECH_TEN_UPGRADE_UNLOCK_PROSPEROUS_VALUE_LIMIT) {
            respMsg.setRet(GameErrorCode.E_MANOR_PROSPEROUS_VALUE_NO_ENOUGH);
            return;
        }
        int lvUpCount = 0;
        int oldLv = technologyData.getSkillLvList().get(skillPos);
        Property cost = new Property();
        for (int i = 0; i < lvCount; i++) {
            if (getSkillMaxLevel(id, skillPos) <= technologyData.getSkillLvList().get(skillPos)) {
                if (i == 0) {
                    respMsg.setRet(GameErrorCode.E_MANOR_TECH_LEVEL_LIMIT);
                    player.getModule(ManorModule.class).syncManorData();
                    return;
                } else {
                    break;
                }
            }
            if (technologyData.getSkillLvList().get(skillPos) >= skillInfo.getMaxLevel()) {
                if (i == 0) {
                    respMsg.setRet(GameErrorCode.E_MANOR_TECH_LEVEL_LIMIT);
                    player.getModule(ManorModule.class).syncManorData();
                    return;
                } else {
                    break;
                }
            }
            SkillUpgradeInfo skillUpgradeInfo = SkillMgr.getSkillUpgradeInfo(skillInfo.getUpgradeType(0), technologyData.getSkillLvList().get(skillPos));
            if (!player.getModule(CurrencyModule.class).removeCurrency(new Property(manorTechnologyConfig.getUpgradeItem(), BigInteger.valueOf(skillUpgradeInfo.getConsumeCount())), eLogMoneyType.Manor, eLogMoneyType.ManorLevelUpTechnologyCost)) {
                if (i == 0) {
                    //触发现金礼包计数
                    player.getModule(AttributeModule.class).addAttribute(ePlayerAttrType.ManorRechargeTriggerTimes, 1);
                    player.notifyListener(eGamePlayerEventType.RechargeManor.getValue(), new ManorRechargeArgs(2, 0));
                    player.notifyListener(eGamePlayerEventType.RechargeManorNew.getValue(), new ManorRechargeArgs(1, 0));
                    respMsg.setRet(GameErrorCode.E_BAG_ITEM_NO_ENOUGH);
                    return;
                } else {
                    break;
                }
            }
            cost.addProperty(new Property(manorTechnologyConfig.getUpgradeItem(), BigInteger.valueOf(skillUpgradeInfo.getConsumeCount())));
            technologyData.levelUpSkill(skillPos);
            lvUpCount++;
        }
        player.getModule(ManorModule.class).addProsperousValue(ManorMgr.getTechnologySkillLvUpProsperousAdd().get(skillPos) * lvUpCount, "科技升级");
        player.getModule(ManorModule.class).syncManorData();
        notifyAdd(id, skillPos);
        LogMgr.addLogManorTechnologySkillLvUp(new LogManorTechnologySkillLvUp(player.getUserId(), id, skillPos, oldLv, lvUpCount, technologyData.getSkillLvList().get(skillPos),
                PropertyHelper.parsePropertyToString(cost), new Date()));
        respMsg.setRet(0);
        respMsg.setLvUpCount(lvUpCount);

        SkillUpgradeInfo newSkillUpgradeInfo = SkillMgr.getSkillUpgradeInfo(skillInfo.getUpgradeType(0), technologyData.getSkillLvList().get(skillPos));
        if(newSkillUpgradeInfo != null){
            if (!player.getModule(CurrencyModule.class).currencyIsEnough(new Property(manorTechnologyConfig.getUpgradeItem(), BigInteger.valueOf(newSkillUpgradeInfo.getConsumeCount())))){
                player.notifyListener(eGamePlayerEventType.RechargeManorNew.getValue(), new ManorRechargeArgs(1, 0));
            }
        }
    }

    public int getSkillMaxLevel(int id, int pos) {
        int maxLv = 0;
        ManorTechnologyConfig manorTechnologyConfig = ManorMgr.getManorTechnologyConfigMap().get(id);
        if (manorTechnologyConfig == null) {
            return maxLv;
        }
        String[] arr = manorTechnologyConfig.getVolumeUpgradeList().split("\\|");
        String[] split = arr[pos].split("-");
        if (split[0].equals("0")) {
            return Integer.MAX_VALUE;
        }
        List<String> upgradeParam = Arrays.asList(split[1].split(";"));
        ManorTechnologyData technologyData = technologyDataMap.get(id);
        if (technologyData == null) {
            return maxLv;
        }
        int needSkillLv = technologyData.getSkillLvList().get(Integer.parseInt(split[0]) - 1);
        if (needSkillLv < Integer.parseInt(upgradeParam.get(0))) {
            return maxLv;
        }
        int gap = (needSkillLv - Integer.parseInt(upgradeParam.get(0))) / (Integer.parseInt(upgradeParam.get(1)) * Integer.parseInt(upgradeParam.get(2)));
        maxLv = Integer.parseInt(upgradeParam.get(1)) * (gap + 1);
        return maxLv;
    }

    public void notifyAdd(int id, int pos) {
        ManorTechnologyConfig manorTechnologyConfig = ManorMgr.getManorTechnologyConfigMap().get(id);
        if (manorTechnologyConfig == null) {
            return;
        }
        List<Integer> volumesIdList = manorTechnologyConfig.getVolumesIdList();
        if (volumesIdList.size() > pos) {
            Integer skillId = volumesIdList.get(pos);
            SkillInfo skillInfo = SkillMgr.getSkillInfo(skillId);
            if (skillInfo != null) {
                if (skillInfo.getType() == eSkillType.ManorBuildingEarnAddRatio.getValue() || skillInfo.getType() == eSkillType.ManorBuildingStaffEarnAddition.getValue()) {
                    player.getModule(EarnSpeedModule.class).scheduleAddSilver();
                } else if (skillInfo.getType() == eSkillType.ManorBeautyIntimacyAddValue.getValue() || skillInfo.getType() == eSkillType.ManorBeautyGlamourAddValue.getValue()) {
                    BeautyModule beautyModule = player.getModule(BeautyModule.class);
                    for (UserBeauty userBeauty : beautyModule.getBeautyMap().values()) {
                        player.getModule(SkinModule.class).recaclBeautyAttr(userBeauty, false); //是否需要加入日志
                    }
                    beautyModule.syncUserBeauty(new ArrayList<>(beautyModule.getBeautyMap().values()), false);
                } else if (skillInfo.getType() == eSkillType.ManorPatronsAbilityAddValue.getValue() || skillInfo.getType() == eSkillType.ManorPatronsQualificationAddValue.getValue()) {
                    player.getModule(PatronsModule.class).onPatronsChange(null);
                }
            }
        }
    }

    public void save() {
        for (ManorTechnologyData technologyData : technologyDataMap.values()) {
            if (technologyData.isInsertOption()) {
                UserManorBusiness.add(technologyData);
            } else if (technologyData.isUpdateOption()) {
                UserManorBusiness.update(technologyData);
            }
        }
    }
}
